package com.shujia.day11;

public class Demo05TryCatch {
    public static void main(String[] args) {
        /*
            TODO 异常捕获
                try
                    ...
                catch (异常的类型 变量名)=> 抓，捕获
                    ...
                Java是一个面向对象的语言，所有的异常类 NullPointerException 也是会有一个对象
                    于是需要使用变量调用对象
         */

        /*
            TODO
                int[] ints = new int[3];
                System.out.println(ints[3]);
                对于代码如果发生错误，那么错误的内容包含有三个方面：
                Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
                    at com.shujia.day11.Demo05TryCatch.main(Demo05TryCatch.java:17)
                异常类型：
                    ArrayIndexOutOfBoundsException
                异常提示信息：
                    3
                错误发生位置：
                     at com.shujia.day11.Demo05TryCatch.main(Demo05TryCatch.java:17)
                对于排除问题的思路：
                    ① 获取完整的日志信息 错误的位置不一定就发生在代码指定的位置
                    ② 找到错误的类型 根据类型可以确定当前问题发生的范围，
                            同时也可以根据类型将错误捕获，让程序继续运行
                    ③ 根据错误的提示信息，寻找线索 提示信息中一般都会打印一些数据
                    ④ 根据代码指定的位置，对其进行debug,重新运行，查看每个变量中的数据是否符合要求
                    ⑤ 如果因为自身对程序的了解不够，导致程序问题寻找不到，那么尝试换种方式

         */

        Exp exp = getExp();

        try {
            exp.printInfo();
        }catch (NullPointerException exception){
            // 如果发生错误了，就可以捕获到错误的对象 对该对象调用其方法
//            System.out.println("错误提示信息:"+ exception.getMessage());
            System.err.println("错误提示信息:"+ exception.getMessage());
            // 打印整个的错误提示信息
            exception.printStackTrace();
            // 如何将日志信息写入到文件中进行保存？
        }

        // TODO 当程序被捕获时，那么可以继续运行代码
        System.out.println("程序执行到这里了....");


        // TODO 对于多行代码中可能会出现有多个错误，但是也不确定

        try {
            System.out.println(3/0);
            int[] ints = new int[2];
            System.out.println(ints[2]);
            // 对于错误类型有两种  ArrayIndexOutOfBoundsException 或者 ArithmeticException
        }catch (ArrayIndexOutOfBoundsException | ArithmeticException exception){
            System.out.println("发生错误了...");
            System.err.println(exception.getMessage());
            exception.printStackTrace();
        }


        /*
            TODO 对于多种错误类型，可以直接使用父类 Exception 表示
                 由于异常也是一个具体的类，也符合对象的多态特性
                    于是子类异常对象可以指向父类 Exception变量 在调用时，
                        比如 printStackTrace 方法是调用其具体对象的
         */

        try {
            System.out.println(3/0);
            int[] ints = new int[2];
            System.out.println(ints[2]);
        }catch (Exception exception){
//            exception.getMessage();
            System.out.println("捕获到了一个异常，但是暂时不知道是什么");
            exception.printStackTrace();
        }


        /*
            给定的异常太过于具体没有捕获到
                TODO 需求：当不管代码是否执行正常，都要执行某些代码..
                    比如：如果对Mysql数据库进行操作，操作过程中代码出错了
                        但是Mysql的连接需要进行关闭，否则对于Mysql数据库来说，有一个连接被占用了
             final格式：
                try{
                    可能发生错误的代码
                }catch(){
                    当指定的错误类型，被获取到后的操作
                }finally{
                    不管代码是否有错误，都会执行..
                }

         */
        try {
            String s = null;
            s.split("");
            System.out.println(3/0);
            int[] ints = new int[2];
            System.out.println(ints[2]);
        }catch (ArrayIndexOutOfBoundsException | ArithmeticException exception){
            System.out.println("捕获到了一个异常，但是暂时不知道是什么");
            exception.printStackTrace();
        }finally {
            System.out.println("不管程序是否有错误，该代码块中得代码都会被执行...");
        }

        System.out.println("该行被打印表示程序正常执行完成...");



    }

    // 假设这是另外一个Jar包或者其他程序员开发的代码 不能进行改变
    public static Exp getExp() {
        return null;
    }
}
